package com.ruoyi.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.PCategory;
import com.ruoyi.system.domain.bo.PCategoryBo;
import com.ruoyi.system.domain.vo.PCategoryVo;
import com.ruoyi.system.mapper.PCategoryMapper;
import com.ruoyi.system.mapper.SysDictDataMapper;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.IPCategoryService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 分类Service业务层处理
 *
 * @author ruoyi
 * @date 2022-08-02
 */
@RequiredArgsConstructor
@Service
public class PCategoryServiceImpl implements IPCategoryService {

    private final PCategoryMapper baseMapper;
    private final SysDictDataMapper sysDictDataMapper;
    private final SysUserMapper sysUserMapper;

    /**
     * 查询分类
     */
    @Override
    public PCategoryVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }


    /**
     * 查询分类列表
     */
    @Override
    public List<PCategoryVo> queryList(PCategoryBo bo) {
        LambdaQueryWrapper<PCategory> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<PCategory> buildQueryWrapper(PCategoryBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<PCategory> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getPid() != null, PCategory::getPid, bo.getPid());
        lqw.eq(StringUtils.isNotBlank(bo.getPath()), PCategory::getPath, bo.getPath());
        lqw.like(StringUtils.isNotBlank(bo.getName()), PCategory::getName, bo.getName());
        lqw.eq(StringUtils.isNotBlank(bo.getType()), PCategory::getType, bo.getType());
        lqw.eq(StringUtils.isNotBlank(bo.getUrl()), PCategory::getUrl, bo.getUrl());
        lqw.eq(StringUtils.isNotBlank(bo.getExtra()), PCategory::getExtra, bo.getExtra());
        lqw.eq(bo.getStatus() != null, PCategory::getStatus, bo.getStatus());
        lqw.eq(bo.getSort() != null, PCategory::getSort, bo.getSort());
        return lqw;
    }

    /**
     * 新增分类
     */
    @Override
    public Boolean insertByBo(PCategoryBo bo) {
        PCategory add = BeanUtil.toBean(bo, PCategory.class);
        add.setType("1");
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改分类
     */
    @Override
    public Boolean updateByBo(PCategoryBo bo) {
        PCategory update = BeanUtil.toBean(bo, PCategory.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(PCategory entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除分类
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        for (Long id : ids) {
            int i = hasChildNode(id);
            if (i > 0) {
                throw new ServiceException("存在下级分类！");
            }
        }

        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    public List<PCategoryVo> queryMyList(PCategoryBo bo) {
        QueryWrapper<PCategory> lqw = Wrappers.query();
        lqw.eq(bo.getPid() != null, "c.pid", bo.getPid());
        lqw.eq(StringUtils.isNotBlank(bo.getType()), "c.type", bo.getType());
        return baseMapper.selectMyList(lqw);
    }

    /**
     * 校验下级是否存在子类
     */
    private int hasChildNode(long id) {
        List<PCategory> categories = baseMapper.selectList(new LambdaQueryWrapper<PCategory>().eq(PCategory::getPid, id));
        if (CollectionUtil.isNotEmpty(categories)) {
            return 1;
        }

        return -1;
    }

    @Override
    public Map<String, Object> vipList() {

        Map<String, Object> map = new HashMap<>();
        map.put("vipList", this.sysDictDataMapper.selectList(new LambdaQueryWrapper<SysDictData>().eq(SysDictData::getDictType, "sys_vip_level")));
        map.put("userMemberId", this.sysUserMapper.selectOne(new LambdaQueryWrapper<SysUser>().select(SysUser::getUserId, SysUser::getMemberId).eq(SysUser::getUserId, LoginHelper.getUserId())).getMemberId());
        return map;
    }

}
